package com.gmscosmo.janus.config;

import com.alibaba.fastjson.JSONObject;
import com.gmscosmo.common.JanusNativeSignaling;
import com.gmscosmo.janus.email.EmailSender;
import com.gmscosmo.janus.util.JanusLogUtil;
import com.gmscosmo.janus.util.JanusUtil;
import com.gmscosmo.model.Node;
import com.gmscosmo.janus.queue.RabbitmqHttpRequestUtil;
import com.gmscosmo.request.JanusRequest;
import com.gmscosmo.janus.sendMessage.JanusAsyncSender;
import com.gmscosmo.janus.util.CommonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author stephen.qiu
 */
@Component
@Configuration
@EnableScheduling
public class CheckJanusServerTask {
    @Autowired
    JanusConfig janusConfig;
    @Autowired
    JanusLogUtil janusLogUtil;
    @Autowired
    RabbitmqHttpRequestUtil rabbitmqHttpRequestUtil;
    @Autowired
    JanusUtil janusUtil;
    @Autowired
    JanusAsyncSender janusAsyncSender;
    @Autowired
    EmailSender emailSender;

    //@Scheduled(cron = "0/5 * * * * ?")
    //或直接指定时间间隔，例如：5秒
    @Scheduled(initialDelay = 15000, fixedRate = 15000)
    private void updateJanusServer() {
        janusLogUtil.log("开始更新janus服务器: " + LocalDateTime.now(),this.getClass(),JanusLogUtil.DEBUG);
        List<String> queues = rabbitmqHttpRequestUtil.getQueueName("to");
        if (queues == null) {
            janusLogUtil.log("未发现janus服务器",this.getClass(), JanusLogUtil.WARN);
        }
        ConcurrentHashMap<Integer, Node> nodeInfos = janusUtil.getNodeInfos();
        for (String queue : queues) {
            String host = rabbitmqHttpRequestUtil.getQueueConsumerHost(queue);
            if (host == null) {
                for(Node n:nodeInfos.values()){
                    if(n.getTo_janus().equals(queue)){
                        if (janusUtil.removeNodeInfo(n.getNodeId())) {
                            janusLogUtil.log("移除janus服务器:"+ n.getHost(),this.getClass(),JanusLogUtil.DEBUG);
                            emailSender.send("移除janus服务器:" + n.getHost());
                        }else{
                            janusLogUtil.log("移除janus服务器:"+ n.getHost()+"失败,被占用",this.getClass(),JanusLogUtil.DEBUG);
                        }
                    }
                }
                continue;
            }
            int nodeId = Math.abs(host.hashCode());
            Node node = new Node();
            node.setNodeId(nodeId);
            if (!nodeInfos.containsKey(node.getNodeId())) {
                node.setClusterId(0);
                node.setHost(host);
                node.setInterHost(queue.split("to-janus")[1]);
                node.setTo_janus(queue);
                node.setParticipant(0);
                janusLogUtil.log("发现新janus节点" + host, this.getClass(), JanusLogUtil.TRACE);
                janusUtil.putNodeInfo(nodeId, node);
                janusLogUtil.log("加载janus服务器:" + host, this.getClass(), JanusLogUtil.DEBUG);
                emailSender.send("加载janus服务器:" + host);
            }
        }
        janusLogUtil.log("更新janus服务器完成: " + LocalDateTime.now()+",当前服务器数量:"+janusUtil.getNodeInfos().size(),this.getClass(),JanusLogUtil.DEBUG);
    }

    private boolean checkJanusServer(Node node) {
        JanusRequest keepaliveRequest = new JanusRequest();
        keepaliveRequest.setJanus(JanusNativeSignaling.KEEP_A_LIVE);
        String transaction = CommonUtils.randomString(12);
        keepaliveRequest.setTransaction(transaction);
        long session_id = 123456789;
        keepaliveRequest.setSession_id(session_id);
        JSONObject response = null;
        try {
            response = janusAsyncSender.sendWithFuture(transaction, true, JSONObject.toJSON(keepaliveRequest).toString(), node.getNodeId()).get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (response == null) {
            janusLogUtil.log(node.getHost()+"检测超时",this.getClass(),JanusLogUtil.TRACE);
            return false;
        }
        janusLogUtil.log(node.getHost()+"检测成功",this.getClass(),JanusLogUtil.TRACE);
        return true;
    }

    @Scheduled(fixedRate = 10000)
    private void checkJanusServers() {
        if(janusConfig.isCheck()) {
            janusLogUtil.log("开始检测janus服务器: " + LocalDateTime.now(), this.getClass(), JanusLogUtil.DEBUG);
            ConcurrentHashMap<Integer, Node> nodeInfos = janusUtil.getNodeInfos();
            for (Node node : nodeInfos.values()) {
                janusLogUtil.log(node.getHost() + "开始检测", this.getClass(), JanusLogUtil.TRACE);
                if (!checkJanusServer(node)) {
                    if (janusUtil.removeNodeInfo(node.getNodeId())) {
                        janusLogUtil.log("移除janus服务器:" + node.getHost(), this.getClass(), JanusLogUtil.DEBUG);
                        emailSender.send("移除janus服务器:" + node.getHost());
                    } else {
                        janusLogUtil.log("移除janus服务器:" + node.getHost() + "失败,被占用", this.getClass(), JanusLogUtil.DEBUG);
                    }
                }
            }
        }
    }
}